#include "outputfunction.h"
//#include <TSettings>
#include "common/tsettings/tsettings.h"
#include "common/common.h"
#include <QDebug>
#include <QTimer>


const int OutputFunction::mOutputNoTab[]=
{
    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
};



OutputFunction *OutputFunction::mInstance = NULL;
#define OUTPUT_IO_COUNTS COUNT_OF(mOutputNoTab)


const QString OutputFunction::OUTPUT_SET="output";
const QString OutputFunction::OPERATION="operation";
const QString OutputFunction::NORMALSTATUS="normalstatus";
const QString OutputFunction::DELAYTIME="delaytime";
const QString OutputFunction::CONTINUETIME="continuetime";

const QString OutputFunction::HI_SET="hi";
const QString OutputFunction::LO_SET="lo";
const QString OutputFunction::POINT_SET="point";

const SendFun OutputFunction::mFunctionList[]=
{
    {NULL,                            QT_TR_NOOP("无")},
//    {SIGNAL(s_trafficIn(Output::Status)),   QT_TR_NOOP("Traffic IN")}, //red
//    {SIGNAL(s_trafficOut(Output::Status)), QT_TR_NOOP("Traffic OUT")},//green
//    {SIGNAL(s_point(Output::Status)), QT_TR_NOOP("Point")},
//    {SIGNAL(s_range(Output::Status)), QT_TR_NOOP("Range")},
//    {SIGNAL(s_stable(Output::Status)),  QT_TR_NOOP("Stable")},
//    {SIGNAL(s_haveTare(Output::Status)), QT_TR_NOOP("Net/Gross")},
    {SIGNAL(s_Start(Output::Status)), QT_TR_NOOP("启动")},
    {SIGNAL(s_High(Output::Status)), QT_TR_NOOP("过量")},
    {SIGNAL(s_OK(Output::Status)),  QT_TR_NOOP("合格")},
    {SIGNAL(s_Low(Output::Status)), QT_TR_NOOP("欠量")},
    {SIGNAL(s_Beep(Output::Status)), QT_TR_NOOP("鸣叫")},
//    {SIGNAL(s_PickOut(Output::Status)), QT_TR_NOOP("剔除")},
    {SIGNAL(s_Ng(Output::Status)), QT_TR_NOOP("不合格")},
//   {SIGNAL(s_Range(Output::Status)), QT_TR_NOOP("分选")},
    {SIGNAL(s_R1(Output::Status)), QT_TR_NOOP("区间1")},
    {SIGNAL(s_R2(Output::Status)), QT_TR_NOOP("区间2")},
    {SIGNAL(s_R3(Output::Status)), QT_TR_NOOP("区间3")},
    {SIGNAL(s_R4(Output::Status)), QT_TR_NOOP("区间4")},
    {SIGNAL(s_R5(Output::Status)), QT_TR_NOOP("区间5")},
    {SIGNAL(s_R6(Output::Status)), QT_TR_NOOP("区间6")},
    {SIGNAL(s_R7(Output::Status)), QT_TR_NOOP("区间7")},
    {SIGNAL(s_R8(Output::Status)), QT_TR_NOOP("区间8")},
    {SIGNAL(s_R9(Output::Status)), QT_TR_NOOP("区间9")},
    {SIGNAL(s_R10(Output::Status)), QT_TR_NOOP("区间10")},
    {SIGNAL(s_R11(Output::Status)), QT_TR_NOOP("区间11")},
    {SIGNAL(s_R12(Output::Status)), QT_TR_NOOP("区间12")},
//    {SIGNAL(s_R13(Output::Status)), QT_TR_NOOP("区间13")},
//    {SIGNAL(s_R14(Output::Status)), QT_TR_NOOP("区间14")},
//    {SIGNAL(s_R15(Output::Status)), QT_TR_NOOP("区间15")},
};

const char* OutputFunction::NORMAL_STATUS[]=
{
//    #if OUT_OPEN == 1
//    QT_TR_NOOP("Normal close"),
//    QT_TR_NOOP("Normal open")
//    #else
//    QT_TR_NOOP("Normal open"),
//    QT_TR_NOOP("Normal close")
//    #endif
    "常闭",
    "常开"
};


#define OPERATION_COUNTS sizeof(mFunctionList)/sizeof(SendFun)



OutputFunction::OutputFunction(QObject *parent) :
    QObject(parent)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    int defaultOp[OUTPUT_IO_COUNTS] = {START,HI,OK,LO,BEEP,PICKOUT,NONE};//前6个默认
    for(int i = 0;i<OUTPUT_IO_COUNTS;++i)
    {
        Output* io = new Output(mOutputNoTab[i]);
        mOutputList<<io;
        set.setArrayIndex(i);
        uint operation = set.value(OPERATION,defaultOp[i]).toUInt();
        uint normalStatus = set.value(NORMALSTATUS,NORMALOPEN).toUInt();
        uint delaytime = set.value(DELAYTIME,0).toUInt();
        uint continuetime = set.value(CONTINUETIME,0).toUInt();
        initOutputFunction(io,operation,normalStatus,delaytime,continuetime);
        io->setStatus(Output::RESET);
    }
    set.endArray();
//    TSettings set(DIR_SETTINGS,TSettings::IniFormat);

//    mStatus = TRAFFIC_UNDEFINED;
//    mOutputList.clear();


//    for(uint i=0;i<OUTPUT_IO_COUNTS;i++)
//    {
//        gpio_init(mOutputTab[i],OUT);
//        Output *io = new Output(mOutputTab[i],this);

//        mOutputList<<io;
//        set.beginGroup(OUTPUT_SET+QString::number(i+1));
//        uint functionNum = set.value(FUNCTION_SET,0).toUInt();
//        uint normalStatus = set.value(STATUS_NORMAL_SET,OUT_OPEN).toUInt();
//        uint startDly = set.value(START_DLY_SET,0).toUInt();
//        uint continueTime = set.value(CONTINUE_TIME,0).toUInt();
//        switch(functionNum)
//        {
//            case RANGE:
//                io->setRange(set.value(LO_SET,0).toFloat(),
//                             set.value(HI_SET,0).toFloat());
//                break;
//            case POINT:
//                io->setPoint(set.value(POINT_SET,0).toFloat());
//                break;
//        }
//       set.endGroup();

//    }
}

OutputFunction *OutputFunction::getOutputFunctionMgr()
{
    if(mInstance==NULL)
        mInstance = new OutputFunction();
    return mInstance;
}


int OutputFunction::outputIoCount()
{
    return OUTPUT_IO_COUNTS;
}

int OutputFunction::OperationCount()
{
    return OPERATION_COUNTS;
}


QStringList OutputFunction::operationNameList()
{
   QStringList list;
   for(uint i =0;i<OPERATION_COUNTS;i++)
   {
       list<<tr(mFunctionList[i].name);
   }
   return list;
}


QStringList OutputFunction::normalStatusList()
{
   QStringList list;
   for(int i =0;i<2;i++)
   {
       list<<tr(NORMAL_STATUS[i]);
   }
   return list;
}


void OutputFunction::initOutputFunction(Output *io,uint functionNum,bool normalStatus,uint startDly,uint continueTime)
{
    if(functionNum>=OPERATION_COUNTS) functionNum = 0;
    disconnect(io,SLOT(setStatus(Output::Status)));
    if(functionNum!=0)
    {
            connect(this,mFunctionList[functionNum].signal,io,SLOT(setStatus(Output::Status)));
    }
    QString name = mFunctionList[functionNum].name;
    io->setStartDly(startDly);
    io->setContinueTime(continueTime);
    io->setNormalStatus(normalStatus);
    io->setOperation(functionNum);
    io->setOptName(name);

}

void OutputFunction::saveOutputFunction(uint num,uint normalStatus,uint functionNum,uint startDly,uint continueTime)
{
//    qDebug()<<"::::::;;;;;;;;;;;::::::::"<<num<<OUTPUT_IO_COUNTS_40<<mOutputList.size();


    if(num>=OUTPUT_IO_COUNTS) return;


    if(normalStatus>1) normalStatus=NORMALOPEN;

    if(functionNum>=OPERATION_COUNTS) functionNum = 0;

    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginWriteArray(OUTPUT_SET);
    //set.beginGroup(OUTPUT_SET+QString::number(num+1));
    set.setArrayIndex(num);
    set.setValue(OPERATION,functionNum);
    set.setValue(NORMALSTATUS,normalStatus);
    set.setValue(DELAYTIME,startDly);
    set.setValue(CONTINUETIME,continueTime);

    Output *io = mOutputList[num];
    initOutputFunction(io,functionNum,normalStatus,startDly,continueTime);
    set.endArray();

}

Output::Range OutputFunction::getOutputRange(uint i)
{
    Output::Range range;
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));
    set.setArrayIndex(i);
    range.hi = set.value(HI_SET,0).toFloat();
    range.lo = set.value(LO_SET,0).toFloat();
    set.endArray();
    return range;
}

float OutputFunction::getOutputPoint(uint i)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));
    float f = set.value(POINT_SET,0).toFloat();
    set.endArray();

    return f;
}

void OutputFunction::saveOutputRange(uint i,Output::Range range)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);


    if(i>=OUTPUT_IO_COUNTS) return;
    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));
    //qDebug()<<OUTPUT_SET+QString::number(i+1)<<"save out put";
    set.setValue(HI_SET,range.hi);
    set.setValue(LO_SET,range.lo);

    set.endArray();
    mOutputList.at(i)->setRange(range.lo,range.hi);
}

void OutputFunction::saveOutputPoint(uint i,float f)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);

    if(i>=OUTPUT_IO_COUNTS) return;

    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));
    set.setValue(POINT_SET,f);
    set.endArray();
    //mOutputList.at(i)->setPoint(f);
}

QString OutputFunction::getOutputSetting(uint i)
{
    QString str;
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));

    uint s  = set.value(NORMALSTATUS,NORMALOPEN).toInt();
    if(s>1) s=0;
    str += NORMAL_STATUS[s];

    str += " - ";
    s = set.value(OPERATION,0).toInt();
    if(s>=OPERATION_COUNTS) s = 0;

    str += mFunctionList[s].name;


//    str += " - ";
//    s  = set.value(START_DLY_SET,0).toInt();
//    str += QString::number(s);
//     str += "/";
//    s  = set.value(CONTINUE_TIME,0).toInt();
//    str += QString::number(s);
//    str += tr("sec");

    set.endArray();
    return str;
}

QString OutputFunction::getOperationName(uint i)
{
    return mFunctionList[i].name;
}

int OutputFunction::getNormalStatus(uint num)
{
    return mOutputList.at(num)->normalStatus();
}

int OutputFunction::getFunctionNum(uint num)
{
    return mOutputList.at(num)->getOperation();
}

int OutputFunction::getStartDlyTime(uint i)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));

    uint s  = set.value(DELAYTIME,0).toInt();

    set.endArray();

    return s;
}

int OutputFunction::getContinueTime(uint i)
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    set.beginReadArray(OUTPUT_SET);
    set.setArrayIndex(i);
    //set.beginGroup(OUTPUT_SET+QString::number(i+1));

    uint s  = set.value(CONTINUETIME,0).toInt();

    set.endArray();

    return s;
}

bool OutputFunction::haveFunction(uint functionNum)
{
    int t = mOutputList.size();
    for(int i=0;i<t;i++)
    {
        if(mOutputList.at(i)->getOperation()==functionNum)
            return true;
    }
    return false;
}

QByteArray OutputFunction::haveFunctionList(uint functionNum)
{
    QByteArray array;
    int t = mOutputList.size();
    for(char i=0;i<t;i++)
    {
        if(mOutputList.at(i)->getOperation()==functionNum)
            array.append(i);
    }
    return array;
}



void OutputFunction::setTrafficStatus(TrafficStatus status)
{
    if(mStatus!=status)
    {
        switch(status)
        {
        case TRAFFIC_NO_WEIGHT:
            emit s_trafficIn(Output::GREEN);
            emit s_trafficOut(Output::RED);
            break;
        case TRAFFIC_WEIGHT_READY:
            if(mStatus==TRAFFIC_NO_WEIGHT)
            {
                emit s_trafficIn(Output::RED);
                emit s_trafficOut(Output::RED);
            }
            break;
        case TRAFFIC_WEIGHT_OK:
            emit s_trafficOut(Output::GREEN);
            emit s_trafficIn(Output::RED);
            break;

        }
        mStatus = status;
    }
}

void OutputFunction::setRangeStatus(int index,Output::Status status)
{
    switch (index) {
    case 0:
        qDebug()<<"index"<<index;
        for(int i = 0;i<OUTPUT_IO_COUNTS;++i)
        {
            if(getStatus(i)==Output::SET)
            {
                qDebug()<<"i"<<i;
                setStatus(i,Output::RESET);
            }
        }
        break;
    case 1:
        emit s_R1(status);
        break;
    case 2:
        emit s_R2(status);
        break;
    case 3:
        emit s_R3(status);
        break;
    case 4:
        emit s_R4(status);
        break;
    case 5:
        emit s_R5(status);
        break;
    case 6:
        emit s_R6(status);
        break;
    case 7:
        emit s_R7(status);
        break;
    case 8:
        emit s_R8(status);
        break;
    case 9:
        emit s_R9(status);
        break;
    case 10:
        emit s_R10(status);
        break;
    case 11:
        emit s_R11(status);
        break;
    case 12:
        emit s_R12(status);
        break;
    default:
        break;
    }
    //emit mFunctionList[index+R1].signal;
}

void OutputFunction::setPointStatus(Output::Status status)
{
//    Q_UNUSED(status)
    emit s_point(status);
}

void OutputFunction::setStableStatus(Output::Status status)
{
//    Q_UNUSED(status)
    emit s_stable(status);
}

void OutputFunction::setTareStatus(Output::Status status)
{
//    Q_UNUSED(status)
    emit s_haveTare(status);
}


void OutputFunction::setCheckNgStatus(Output::Status status)
{
    emit s_Ng(status);
}

void OutputFunction::setCheckHighStatus(Output::Status status)
{
//    Q_UNUSED(status)
    emit s_High(status);
}
void OutputFunction::setCheckOKStatus(Output::Status status)
{
//    Q_UNUSED(status)
    emit s_OK(status);
}
void OutputFunction::setCheckLowStatus(Output::Status status)
{
//    Q_UNUSED(status)

    emit s_Low(status);
}

void OutputFunction::setCheckBeepStatus(Output::Status status)
{
//    Q_UNUSED(status)
//    qDebug()<<"=====------------------>";
    emit s_Beep(status);
}



void OutputFunction::setStartStatus(Output::Status status)
{
    emit s_Start(status);
}


void OutputFunction::setWeightOkStatus(Output::Status status)
{
    emit s_Weight(status);
}

//void OutputFunction::setPickOutStatus(Output::Status status)
//{
//    emit s_PickOut(status);
//}

void OutputFunction::checkWeight(float w)
{
    int t = mOutputList.size();
    for(int i=0;i<t;i++)
    {
        Output *io = mOutputList.at(i);
        if(io->getOperation()>=R1)
        {
            io->checkRange(w);
        }
//        switch(io->getOperation())
//        {
//        case RANGE:
//            io->checkRange(w);
//            break;
//        case POINT:
//            io->checkPoint(w);
//            break;
//        default:
//            break;
//        }
    }
}

void OutputFunction::setStatus(uint num, Output::Status status)
{
    mOutputList.at(num)->setStatus(status);
}

Output::Status OutputFunction::getStatus(uint num)
{
    return mOutputList.at(num)->getStatus();
}
